/*-------------------------------------------------------------------------
 - Copyright (c) 2024-2025 [XD-AMCC TEAM]
 - [XD-AMCC] is licensed under Mulan PSL v2.
 - You can use this software according to the terms and conditions of the Mulan PSL v2.
 - You may obtain a copy of Mulan PSL v2 at:
 -          http://license.coscl.org.cn/MulanPSL2
 - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
 - OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 - TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 - See the Mulan PSL v2 for more details.
 ------------------------------------------------------------------------*/


/**
 * @brief Inner operations of class token.
 *
 * @author  WXQ#XDU
 * @date    2024.11
 */

#include <stdio.h>   // for snprintf()
#include <stdlib.h>  // for bsearch()
#include <string.h>

#include "_lex_inner.h"


t_token_body * token_body_new (const char * cString, EnumTokenKind kind) {
    t_token_body * pThis = (t_token_body *)calloc(1, sizeof(t_token_body));
    pThis->kind = kind;
    pThis->inputText = string_new(cString, (int)(strlen(cString))) ;
    memset(&(pThis->value), 0, sizeof(pThis->value));
    return pThis;
}

void token_body_destroy (t_token_body * pThis) {
    if (NULL == pThis)
        return;
    string_destroy(pThis->inputText);
    pThis->inputText = NULL;
    free(pThis);
}


t_token_ptr token_new (const char* cString, EnumTokenKind kind,
                       t_lexer_ptr pLexer,
                       int line, int col )
{
    const char * filePath = "<NIL>";
    if (NULL != pLexer) {
        filePath = pLexer->inputFilePath;
    }
    t_token_body * pBody = tokenpool_put(cString, kind, line, col, filePath);
    t_token_ptr pThis = (t_token_ptr)calloc(1, sizeof(t_token));
    pThis->tokenBody = pBody;
    if (NULL == pLexer) {
        pThis->pos.filePath = "<NIL>";
    } else {
        pThis->pos = pLexer->currentPosition;
    }
    return pThis;
}

void token_destroy (t_token_ptr pThis) {
    if (NULL == pThis) return;
    // token_body_destroy(pThis->tokenBody);  // body MUST be destroyed by token-pool
    pThis->tokenBody = NULL;
    free(pThis);
}


void token_set_position (t_token_ptr pThis, t_position pos) {
    if (NULL == pThis) return;
    pThis->pos = pos;
}

extern t_position_ptr token_zero_position();


// Creates a new token marker with EPSILON.
// This function is ONLY be used in building parse tree.
//
t_token_ptr token_new_epsilon (t_position_ptr positionPtr)  {
    t_token_ptr pThis = token_new(EPSILON_TEXT, TK_EPSILON, NULL, 0, 0);
    if (NULL != positionPtr) {
        pThis->pos = *positionPtr;
    } else {
        pThis->pos.filePath = "<NIL>";
    }
    return pThis;
}

t_token_ptr token_new_pseudo (const char * txt, EnumTokenKind kind)  {
    t_token_ptr pThis = token_new(txt, kind, NULL, 0, 0);
    return pThis;
}

